package org.footballmanager.pandafootball.system.controller;

import lombok.extern.slf4j.Slf4j;
import org.footballmanager.pandafootball.common.constants.Constants;
import org.footballmanager.pandafootball.common.util.MD5Encoder;
import org.footballmanager.pandafootball.common.util.MakeCookie;
import org.footballmanager.pandafootball.common.util.RandomNumber;
import org.footballmanager.pandafootball.common.util.VerifyCodeUtil;
import org.footballmanager.pandafootball.system.domain.*;
import org.footballmanager.pandafootball.system.domain.enums.QX;
import org.footballmanager.pandafootball.system.service.*;
import org.footballmanager.pandafootball.system.service.impl.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Controller
public class UserLoginController {
	private static final String EMAIL = "email";
	private static final String NAME = "name";
	private static final String LOGINPAGE = "main/login";
	private static final String REGISTPAGE = "main/regist";
	private static final String FORGETPAGE = "main/forgetpwd";
	private static final String FORGETPAGE2 = "main/forgetpwd2";
	private static final String REDIRECTINDEX = "redirect:/index";
	private static final String REDIRECTLOGIN = "redirect:/login";
	private static final String CODE = "validateCodeRecruit";

	@Autowired
	private FootUserService footUserService;
	@Autowired
	private FootYysService footYysService;
	@Autowired
	private FootTeamService footTeamService;
	@Autowired
	private FootClubService footClubService;
	@Autowired
	private FootSjService footSjService;
	@Autowired
	private FootZnxService footZnxService;
	@Autowired
	private FootLyService footLyService;
	@Autowired
	private FootQdService footQdService;
	@Autowired
	private FootGpService footGpService;
	@Autowired
	private FootBfinfoService footBfinfoService;
	@Autowired
	private FootScinfoService footScinfoService;
	@Autowired
	private FootPersonService footPersonService;
	@Autowired
	private PhotoService photoService;
	@Autowired
	private FootXfService footXfService;
	@Autowired
	private RedisService redisService;

	@ModelAttribute
	public void init1(Model map){
		map.addAttribute("userList", footUserService.getall());
		map.addAttribute("clubList", footClubService.getall());
		map.addAttribute("qdList", footQdService.getall());
		map.addAttribute("qyList", footPersonService.getall());
		map.addAttribute("sjList", footSjService.getall());
	}
	
	@RequestMapping(value="/login", method= RequestMethod.GET)
	public String login(Model map, HttpServletRequest request) {
		request.getSession().setAttribute("title", redisService.get("title"));
		map.addAttribute(Constants.USER, new FootUser());
		map.addAttribute(Constants.YQTS, RandomNumber.randomContent(redisService));
		return LOGINPAGE;
	}
	
	@RequestMapping(value="/login", method= RequestMethod.POST)
	public String loginPost(Model map, @Valid @ModelAttribute FootUser footUser,
			BindingResult bindingResult, HttpServletRequest request, HttpServletResponse response, String rememberme) {
		FootUser user = footUserService.findUserByName(footUser.getName());
		boolean processLoginError = processLoginError(map, bindingResult, footUser, user, request);
		boolean processYzmError = processYzmError(map, bindingResult, footUser, request);
		if(!processLoginError || !processYzmError){
			return LOGINPAGE;
		}
        user.setZhdlsj(new Date());
        user.setIp(request.getRemoteAddr());
        footUserService.updateAll(user, request);
		processLoginSession(request, user, rememberme, footUser, response);
        return REDIRECTINDEX;
	}

	private void processLoginSession(HttpServletRequest request, FootUser user, String rememberme, @Valid FootUser footUser, HttpServletResponse response){
		request.getSession().setAttribute(Constants.USER, user);
		if(null != rememberme && "1".equals(rememberme)){
			MakeCookie.addCookie(response, "username", footUser.getName());
			MakeCookie.addCookie(response, "password", footUser.getPassword());
		}
		Long logo = footTeamService.getLogoByUserid(user.getId());
		if(null != logo){
			Photo photo = photoService.get(logo);
			request.getSession().setAttribute(Constants.LOGO, photo.getUrl());
		}
		Long slt = footTeamService.getSltByUserid(user.getId());
		if(null != slt){
			Photo photo = photoService.get(slt);
			request.getSession().setAttribute(Constants.SLT, photo.getUrl());
		}
		request.getSession().setAttribute("nowTime", new Date());
		request.getSession().setAttribute(Constants.USERID, user.getId());
	}

	private boolean processLoginError(Model map, BindingResult bindingResult, FootUser footUser, FootUser user, HttpServletRequest request){
		if(request.getSession(true).isNew()){
			return false;
		}
		//session不失效
//		req.getSession().setMaxInactiveInterval(-1)
		if(user == null){
			bindingResult.rejectValue(NAME, Constants.MISFORMAT, "无此用户注册信息");
			map.addAttribute(Constants.YQTS, RandomNumber.randomContent(redisService));
			return false;
		}
		String pwd = MD5Encoder.strToMD5(footUser.getPassword());
		if(!user.getPassword().equals(pwd)) {
			bindingResult.rejectValue(NAME, Constants.MISFORMAT, "用户名或密码不对,请检查");
			map.addAttribute(Constants.YQTS, RandomNumber.randomContent(redisService));
			return false;
		}
		if(user.getSd()) {
			bindingResult.rejectValue(NAME, Constants.MISFORMAT, "账号被锁定,请联系GM");
			map.addAttribute(Constants.YQTS, RandomNumber.randomContent(redisService));
			return false;
		}
		return true;
	}

	private boolean processYzmError(Model map, BindingResult bindingResult, FootUser footUser, HttpServletRequest request){
		String code = request.getSession().getAttribute(CODE).toString();
		if(StringUtils.isEmpty(code) || StringUtils.isEmpty(footUser.getYzm())){
			bindingResult.rejectValue(Constants.YZM, Constants.MISFORMAT, "验证码不能为空");
			map.addAttribute(Constants.YQTS, RandomNumber.randomContent(redisService));
			return false;
		}
		String validatorcode = footUser.getYzm().toLowerCase();
		if(!validatorcode.equals(code)){
			bindingResult.rejectValue(Constants.YZM, Constants.MISFORMAT, "验证码出错");
			map.addAttribute(Constants.YQTS, RandomNumber.randomContent(redisService));
			return false;
		}
		return true;
	}

    /**
     * 图形验证码生成方法
     * @param response 响应
     * @param request 请求
     * @throws IOException 异常
     */
    @RequestMapping("/verifyCode")
    public void verifyCode(HttpServletResponse response, HttpServletRequest request) throws IOException{
        //利用图片工具生成图片
        //第一个参数是生成的验证码，第二个参数是生成的图片
        Object[] objs = VerifyCodeUtil.createImage();
        //将验证码存入Session
        request.getSession().setAttribute(CODE, objs[0]);

        //将图片输出给浏览器
        BufferedImage image = (BufferedImage) objs[1];
        response.setContentType("image/png");
        OutputStream os = response.getOutputStream();
        ImageIO.write(image, "png", os);
    }

    @RequestMapping(value="/regist", method= RequestMethod.GET)
	public String pageLoad(Model map) {
		map.addAttribute(Constants.USER, new FootUser());
		return REGISTPAGE;
	}
	
	@RequestMapping(value="/regist", method= RequestMethod.POST)
	public String regist(@Valid @ModelAttribute FootUser footUser, BindingResult bindingResult,
			HttpServletRequest request) {
		String code = String.valueOf(request.getSession().getAttribute(CODE));
		String validatorcode = footUser.getYzm().toLowerCase();
		if(!validatorcode.equals(code)){
            bindingResult.rejectValue(Constants.YZM, Constants.MISFORMAT, "验证码出错");
		}
		FootUser user = footUserService.findUserByName(footUser.getName());
		if(user != null){
			bindingResult.rejectValue(NAME, Constants.MISFORMAT, "此用户已注册,请更换用户名");
		}
		List<FootUser> userList = footUserService.findUsersByNike(footUser.getNike());
		if(user != null && !userList.isEmpty()){
			bindingResult.rejectValue("nike", Constants.MISFORMAT, "此昵称已注册,请更换昵称");
		}
		if (bindingResult.hasErrors()) {
			return REGISTPAGE;
		}
		footUser.setJoins(true);
		footUser.setZhdlsj(new Date());
		footUser.setIp(request.getRemoteAddr());
		request.getSession().setAttribute(Constants.USER, footUser);
		if("".equals(footUser.getGameId())){
			bindingResult.rejectValue("gameId", Constants.MISFORMAT, "游戏ID不能为空");
			return REGISTPAGE;
		}
		footUserService.save(footUser, request);
		return REDIRECTINDEX;
	}
	
	@RequestMapping(value="/index", method= RequestMethod.GET)
	public String index(Model map, HttpServletRequest request) {
		FootUser user = (FootUser)request.getSession().getAttribute(Constants.USER);
        processLy(map);
		request.getSession().setAttribute("sjInfo", footSjService.getRunningSj());
		//获取当前赛季信息
		if(!user.getQx().equals(QX.ADMIN) && !user.getQx().equals(QX.NORMAL)){
            processScInfo(user, map);
            processOthers(user, map);
            return "main/index_hy";
		}else if(user.getQx().equals(QX.NORMAL)){//一般用户
            processNormal(map, user);
			return "main/index_normal";
		}else{
			return "main/index_admin";
		}
	}

	private void processNormal(Model map, FootUser user){
        List<FootYys> yyslist = footYysService.findYysTop10();
        map.addAttribute("yysList", yyslist);
        //排位赛积分榜
        List<FootYys> list = footYysService.getJfb();
        map.addAttribute("jfb", list);
        //已完成比赛信息
        List<FootBfinfo> bflist = footBfinfoService.findYysByUserId(user.getId());
        map.addAttribute("yws", bflist);
    }

	private void processOthers(FootUser user, Model map){
        //已完成比赛信息
        List<FootBfinfo> bflist = footBfinfoService.getSubmitData(user.getId(), footSjService.getSj());
        map.addAttribute("yws", bflist);
        //挂牌球员信息
        List<FootGp> gpList = footGpService.findGpNotSuccess();
        map.addAttribute("gpList", gpList);
        //解约球员信息
        List<FootXf> xflist = footXfService.findXfByTimeDesc();
        map.addAttribute("xfList", xflist);
        // 根据用户的常规赛类别取当前常规赛的积分榜
        List<FootClub> list = footClubService.getScoreboard(false, footSjService.getSj());
        map.addAttribute("jfb", list);
        //排位赛榜
        List<FootYys> yyslist = footYysService.findYysTop10();
        map.addAttribute("yysList", yyslist);
    }

	private void processScInfo(FootUser user, Model map){
        //获取用户收藏信息
        List<FootScinfo> scList = footScinfoService.findCollectionByUserId(user.getId());
        if(scList != null && !scList.isEmpty()){
            List<FootPerson> listperson = new ArrayList<>();
            for(FootScinfo sc: scList){
                listperson.add(footPersonService.get(sc.getQyId()));
            }
            map.addAttribute("mysc", listperson);
        }
    }

	private void processLy(Model map){
        //公告板
        List<FootLy> lylist = footLyService.findLyBySendtimeDesc();
        if(lylist.size() > 5){
            map.addAttribute("lyList", lylist.subList(0, 5));
        }else{
            map.addAttribute("lyList", lylist);
        }
    }

	@RequestMapping(value = "/logout", method = RequestMethod.GET)
	public String logout(HttpServletRequest request){
		request.getSession().removeAttribute(NAME);
		return REDIRECTLOGIN;
	}
	
	@RequestMapping(value = "/forgetpwd", method = RequestMethod.GET)
	public String forgetpwd(Model map) {
		map.addAttribute(Constants.USER, new FootUser());
		return FORGETPAGE;
	}
	
	@RequestMapping(value = "/forgetpwd", method = RequestMethod.POST)
	public String forgetpwd(Model map, @ModelAttribute FootUser footUser, BindingResult bindingResult){
        String result = processForgetPwdError(footUser, bindingResult);
        if(!result.equals(Constants.OK)){
            return result;
        }
		FootUser user = footUserService.findUserByNameEmail(footUser.getName(), footUser.getEmail());
		if(user != null){
			if(StringUtils.isEmpty(user.getQes1()) || StringUtils.isEmpty(user.getQes2())){
                bindingResult.rejectValue(NAME, Constants.MISFORMAT, "该用户未设置密码找回!");
				return FORGETPAGE;
			}
			map.addAttribute(Constants.USER, user);
			return FORGETPAGE2;
		}else{
            bindingResult.rejectValue(EMAIL, Constants.MISFORMAT, "该用户或电子邮件未注册!");
			return FORGETPAGE;
		}
	}

	private String processForgetPwdError(FootUser footUser, BindingResult bindingResult){
        if(StringUtils.isEmpty(footUser.getEmail())){
            bindingResult.rejectValue(EMAIL, Constants.MISFORMAT, "电子邮件不能为空");
            return FORGETPAGE;
        }
        if(StringUtils.isEmpty(footUser.getName())){
            bindingResult.rejectValue(NAME, Constants.MISFORMAT, "用户名不能为空");
            return FORGETPAGE;
        }
        return Constants.OK;
    }
	
	@RequestMapping(value = "/forgetpwd2", method = RequestMethod.POST)
	public String forgetpwd2(@ModelAttribute FootUser footUser, BindingResult bindingResult,
			HttpServletRequest request){
		if(StringUtils.isEmpty(footUser.getAns1()) || StringUtils.isEmpty(footUser.getAns2())){
			bindingResult.rejectValue("ans1", Constants.MISFORMAT, "没有填写回答,请重新确认");
			return FORGETPAGE2;
		}
		String id = request.getParameter(Constants.USERID);
		FootUser user = footUserService.get(id);
		if(user.getAns1().equals(footUser.getAns1()) && user.getAns2().equals(footUser.getAns2())){
			user.setPassword(MD5Encoder.strToMD5("123456"));
			footUserService.updateNotNull(user, request);
			request.getSession().setAttribute("user", user);
			return REDIRECTINDEX;
		}else if(!user.getAns1().equals(footUser.getAns1())){
			bindingResult.rejectValue("ans1", Constants.MISFORMAT, "问题回答错误");
			return FORGETPAGE2;
		}else{
			bindingResult.rejectValue("ans2", Constants.MISFORMAT, "问题回答错误");
			return FORGETPAGE2;
		}
	}
	
	@RequestMapping(value = "/getcookie", method = RequestMethod.POST)
	@ResponseBody
	public String getcookie(HttpServletRequest request){
		Cookie un = MakeCookie.getCookieByName(request, "username");
		Cookie pwd = MakeCookie.getCookieByName(request, "password");
		if(null != un && null != pwd){
			return un.getValue() + Constants.COMMA + pwd.getValue();
		}else{
			return Constants.ERROR;
		}
	}
	
	@RequestMapping(value = "/deleteznx", method = RequestMethod.GET)
	public String deleteznx(@RequestParam Long id, HttpServletRequest request) {
		footZnxService.delete(id, request);
		return REDIRECTINDEX;
	}

	@RequestMapping(value = "/help", method = RequestMethod.GET)
	public String help() {
		return "help/help";
	}

}
